﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Drawing;
using System.IO;

namespace L9SubSet.lwf
{
	public class LwfXmlRead
	{
		// 从 lwf 文件中读取 xml 部分
		public static int ReadXmlFormLwf(string srcLwfFile, string desXmlfile)
		{
			// 判断文件是否存在
			if (File.Exists(srcLwfFile) == false)
			{
				return -1;
			}

			FileStream fsfile = new FileStream(srcLwfFile, FileMode.Open);
			FileStream fsxmlfile = new FileStream(desXmlfile, FileMode.Create);
			if (fsfile.Length == 0)
			{
				return -1;
			}

			byte[] srcFileBytes = new byte[fsfile.Length];

			BinaryWriter bw = new BinaryWriter(fsxmlfile);
			fsfile.Read(srcFileBytes, 0, (int)fsfile.Length);

			int length = srcFileBytes[0x26] << 24 | srcFileBytes[0x27] << 16 | srcFileBytes[0x28] << 8 | srcFileBytes[0x29];

			byte[] desfilebyte = new byte[length];
			for (int i = 0; i < length; i++)
			{
				desfilebyte[i] = srcFileBytes[0x100 + i];
			}
			bw.Write(desfilebyte);

			bw.Close();
			fsxmlfile.Close();
			fsfile.Close();

			return 1;
		}

		public static int ReadFromXml(XmlTextReader rrr, int vvv)
		{
			int read_end = 0;

			while (rrr.Read())
			{
				switch (rrr.NodeType)
				{
					case XmlNodeType.Element:
						break;
					case XmlNodeType.Text:
						vvv = Convert.ToInt32(rrr.Value);
						break;
					case XmlNodeType.EndElement:
						read_end = 1;
						break;
					case XmlNodeType.Comment:
						break;
				}

				if (read_end == 1)
				{
					break;
				}
			}

			return vvv;
		}

		public static string ReadFromXml(XmlTextReader rrr, string vvv)
		{
			int read_end = 0;

			while (rrr.Read())
			{
				switch (rrr.NodeType)
				{
					case XmlNodeType.Element:
						break;
					case XmlNodeType.Text:
						vvv = rrr.Value;
						break;
					case XmlNodeType.EndElement:
						read_end = 1;
						break;
					case XmlNodeType.Comment:
						break;
				}

				if (read_end == 1)
				{
					break;
				}
			}

			return vvv;
		}

		public static Point ReadFromXml(XmlTextReader rrr, Point vvv)
		{
			int read_end = 0;

			while (rrr.Read())
			{
				switch (rrr.NodeType)
				{
					case XmlNodeType.Element:
						if (rrr.Name == "x")
							vvv.X = ReadFromXml(rrr, vvv.X);
						else if (rrr.Name == "y")
							vvv.Y = ReadFromXml(rrr, vvv.Y);
						break;
					case XmlNodeType.Text:
						break;
					case XmlNodeType.EndElement:
						read_end = 1;
						break;
					case XmlNodeType.Comment:
						break;
				}

				if (read_end == 1)
				{
					break;
				}
			}

			return vvv;
		}

		public static List<Point> ReadFromXml(XmlTextReader rrr, List<Point> vvv)
		{
			int read_end = 0;
			int t_num = 0;
			Point ppp;
			vvv.Clear();

			while (rrr.Read())
			{
				switch (rrr.NodeType)
				{
					case XmlNodeType.Element:
						if (rrr.Name == "t_num")
						{
							t_num = ReadFromXml(rrr, t_num);
						}
						else
						{
							ppp = new Point();
							ppp = ReadFromXml(rrr, ppp);
							vvv.Add(ppp);
						}
						break;
					case XmlNodeType.Text:
						break;
					case XmlNodeType.EndElement:
						read_end = 1;
						break;
					case XmlNodeType.Comment:
						break;
				}

				if (read_end == 1)
				{
					break;
				}
			}

			return vvv;
		}

		public static PortTubeData ReadFromXml(XmlTextReader rrr, PortTubeData vvv)
		{
			int read_end = 0;

			while (rrr.Read())
			{
				switch (rrr.NodeType)
				{
					case XmlNodeType.Element:
						if (rrr.Name == "TubeColor")
						{
							vvv.TubeColor = ReadFromXml(rrr, vvv.TubeColor);
						}
						else if (rrr.Name == "WireColor")
						{
							vvv.WireColor = ReadFromXml(rrr, vvv.WireColor);
						}
						else if (rrr.Name == "TubePoint")
						{
							vvv.TubePoint = ReadFromXml(rrr, vvv.TubePoint);
							for (int i = 0; i < vvv.TubePoint.Count; i++)
							{
								vvv.TubeMode.Add(0);
							}
							vvv.MaxRect = MeasurePortRect(vvv.TubePoint);
						}
						else if (rrr.Name == "ColorType")
						{
							vvv.ColorType = ReadFromXml(rrr, vvv.ColorType);
						}
						break;
					case XmlNodeType.Text:
						break;
					case XmlNodeType.EndElement:
						read_end = 1;
						break;
					case XmlNodeType.Comment:
						break;
				}

				if (read_end == 1)
				{
					break;
				}
			}

			return vvv;
		}

		public static List<PortTubeData> ReadFromXml(XmlTextReader rrr, List<PortTubeData> vvv)
		{
			int read_end = 0;
			int p_num = 0;
			PortTubeData ppp;
			vvv.Clear();

			while (rrr.Read())
			{
				switch (rrr.NodeType)
				{
					case XmlNodeType.Element:
						if (rrr.Name == "p_num")
							p_num = ReadFromXml(rrr, p_num);
						else
						{
							ppp = new PortTubeData();
							ppp = ReadFromXml(rrr, ppp);
							vvv.Add(ppp);
						}
						break;
					case XmlNodeType.Text:
						break;
					case XmlNodeType.EndElement:
						read_end = 1;
						break;
					case XmlNodeType.Comment:
						break;
				}

				if (read_end == 1)
				{
					break;
				}
			}

			return vvv;
		}

		public static SubTubeData ReadFromXml(XmlTextReader rrr, SubTubeData vvv)
		{
			int read_end = 0;

			while (rrr.Read())
			{
				switch (rrr.NodeType)
				{
					case XmlNodeType.Element:
						if (rrr.Name == "PortData")
						{
							vvv.PortData = ReadFromXml(rrr, vvv.PortData);
						}
						break;
					case XmlNodeType.Text:
						break;
					case XmlNodeType.EndElement:
						read_end = 1;
						break;
					case XmlNodeType.Comment:
						break;
				}

				if (read_end == 1)
				{
					break;
				}
			}

			return vvv;
		}

		public static List<SubTubeData> ReadFromXml(XmlTextReader rrr, List<SubTubeData> vvv)
		{
			int read_end = 0;
			int s_num = 0;
			SubTubeData ppp;
			vvv.Clear();

			while (rrr.Read())
			{
				switch (rrr.NodeType)
				{
					case XmlNodeType.Element:
						if (rrr.Name == "s_num")
						{
							s_num = ReadFromXml(rrr, s_num);
						}
						else
						{
							ppp = new SubTubeData();
							ppp = ReadFromXml(rrr, ppp);
							vvv.Add(ppp);
						}
						break;
					case XmlNodeType.Text:
						break;
					case XmlNodeType.EndElement:
						read_end = 1;
						break;
					case XmlNodeType.Comment:
						break;
				}

				if (read_end == 1)
				{
					break;
				}
			}

			return vvv;
		}

		public static ColorData ReadFromXml(XmlTextReader rrr, ColorData vvv)
		{
			int read_end = 0;

			while (rrr.Read())
			{
				switch (rrr.NodeType)
				{
					case XmlNodeType.Element:
						if (rrr.Name == "index")
							vvv.index = ReadFromXml(rrr, vvv.index);
						else if (rrr.Name == "name")
							vvv.name = ReadFromXml(rrr, vvv.name);
						break;
					case XmlNodeType.Text:
						break;
					case XmlNodeType.EndElement:
						read_end = 1;
						break;
					case XmlNodeType.Comment:
						break;
				}

				if (read_end == 1)
				{
					break;
				}
			}

			return vvv;
		}

		public static List<ColorData> ReadFromXml(XmlTextReader rrr, List<ColorData> vvv)
		{
			int read_end = 0;
			int c_num = 0;
			ColorData ppp;
			vvv.Clear();

			while (rrr.Read())
			{
				switch (rrr.NodeType)
				{
					case XmlNodeType.Element:
						if (rrr.Name == "c_num")
						{
							c_num = ReadFromXml(rrr, c_num);
						}
						else
						{
							ppp = new ColorData();
							ppp = ReadFromXml(rrr, ppp);
							vvv.Add(ppp);
						}
						break;
					case XmlNodeType.Text:
						break;
					case XmlNodeType.EndElement:
						read_end = 1;
						break;
					case XmlNodeType.Comment:
						break;
				}

				if (read_end == 1)
				{
					break;
				}
			}

			return vvv;
		}

		public static Rectangle MeasurePortRect(List<Point> pts)
		{
			Rectangle rect = new Rectangle();
			
			if (pts.Count == 0)
			{
				return rect;
			}

			int min_x = pts.Min(p => p.X);
			int max_x = pts.Max(p => p.X);
			int min_y = pts.Min(p => p.Y);
			int max_y = pts.Max(p => p.Y);

			rect.X = min_x;
			rect.Y = min_y;
			rect.Width = max_x - min_x;
			rect.Height = max_y - min_y;

			return rect;
		}
	}
}
